<template>
  <a-menu
    v-model:selectedKeys="selectedKeys"
    :theme="props.theme"
    mode="inline"
    :open-keys="openKeys"
    @click="onMenuClick"
    @openChange="onOpenChange"
  >
    <a-menu-item key="0">
      <router-link to="/index">
        <component :is="proxy.$icons['PieChartOutlined']" />
        <span>首页</span>
      </router-link>
    </a-menu-item>
    <template v-for="item in menus" :key="item.id">
      <template v-if="!item.children">
        <a-menu-item :key="item.id">
          <router-link :to="item.uri">
            <component :is="proxy.$icons[item.icon]" />
            <span>
                {{ item.title }}
            </span>
          </router-link>
        </a-menu-item>
      </template>
      <template v-else>
        <sub-menu :key="item.id" :menu-info="item" />
      </template>
    </template>
  </a-menu>
</template>

<script setup lang='ts'>
import { ref, onMounted, watchEffect, getCurrentInstance } from 'vue'
import { useRouter } from 'vue-router'
import { IMenus } from '@/types/menuTypes'
import { deepCopy } from '@/utils/deepCopy'

// 生命周期函数
onMounted(() => {
  getSelectedMenus()
})

// 单文件菜单递归
const SubMenu = {
  name: 'SubMenu',
  props: {
    menuInfo: {
      type: Object,
      default: () => ({})
    }
  },
  template: `
    <a-sub-menu :key="menuInfo.id">
      <template #icon>
        <component :is="$icons[menuInfo.icon]" />
      </template>
      <template #title>{{ menuInfo.title }}</template>
      <template v-for="item in menuInfo.children" :key="item.id">
        <template v-if="!item.children">
          <a-menu-item :key="item.id">
            <router-link :to="item.uri">
              <component :is="$icons[item.icon]" />
              <span>
                  {{ item.title }}
              </span>
            </router-link>
          </a-menu-item>
        </template>
        <template v-else>
          <sub-menu :menu-info="item" :key="item.id" />
        </template>
      </template>
    </a-sub-menu>
  `
}

// 当前打开的按钮(变量)
const openKeys = ref<string[]>()
const oleOpenKeys = ref<string[]>()
// 父子菜单列表
const rootSubmenuKeys: Map<string, string[]> = new Map()
// 父子教程名称
const rootSubmenuNames: Map<String, string[]> = new Map()
// 默认选择按钮
const selectedKeys = ref<string[]>()
// 菜单
const menus = ref<IMenus[]>()

// 声明上下文
const { proxy }: any = getCurrentInstance()
// 获取上下文对象props，从中获取参数
const props = defineProps(
  {
    theme: String,
    collapsed: Boolean
  }
)

// 监听函数
watchEffect(() => {
  if (!props.collapsed) {
    openKeys.value = oleOpenKeys.value
  }
})

// 获取父组件按钮事件
const emit = defineEmits(['clickMenu'])

// 加载判断路由地址
const getSelectedMenus = () => {
  // 获取页面路由
  const router = useRouter()
  const path = router.currentRoute.value.path
  if (path === '/index') {
    selectedKeys.value = ['0']
  } else {
    if (menus.value) {
      rootSubmenuKeys.set('0', ['0'])
      rootSubmenuNames.set('0', ['首页'])
      getSelectedMenusKeys(menus.value, path, [], [])
      if (selectedKeys.value) {
        const selectKeys: string[] = selectedKeys.value
        openKeys.value = rootSubmenuKeys.get(selectKeys[0])
        emit('clickMenu', rootSubmenuNames.get(selectKeys[0]))
      }
    }
  }
}
// 递归方式获取路由对应的key+name
const getSelectedMenusKeys = (menu: IMenus[] | null, path: string, keys: string[], names: string[]) => {
  if (menu !== null) {
    for (let index = 0; index < menu.length; index++) {
      if (menu[index].children) {
        keys.push(menu[index].id)
        names.push(menu[index].title)
        rootSubmenuKeys.set(menu[index].id, deepCopy(keys))
        rootSubmenuNames.set(menu[index].id, deepCopy(names))
        getSelectedMenusKeys(menu[index].children, path, keys, names)
      } else {
        keys.push(menu[index].id)
        names.push(menu[index].title)
        rootSubmenuKeys.set(menu[index].id, deepCopy(keys))
        rootSubmenuNames.set(menu[index].id, deepCopy(names))
        if (menu[index].uri === path) {
          const keys: string[] = [menu[index].id]
          selectedKeys.value = keys
        }
        keys.pop()
        names.pop()
      }
    }
    keys.pop()
    names.pop()
  }
}

// 修改打开子菜单的按钮
const onOpenChange = (openKey: string[]) => {
  const latestOpenKey = openKey.find(key => {
    if (openKeys.value) {
      return openKeys.value.indexOf(key) === -1
    }
    return ''
  })
  if (latestOpenKey) {
    openKeys.value = rootSubmenuKeys.get(latestOpenKey)
    if (!props.collapsed) {
      oleOpenKeys.value = openKeys.value
    }
  }
}

// 点击按钮事件
const onMenuClick = (item: any) => {
  oleOpenKeys.value = rootSubmenuKeys.get(item.key)
  emit('clickMenu', rootSubmenuNames.get(item.key))
}

// 模拟数据
menus.value = [
  {
    id: '1',
    title: 'Option 1',
    icon: 'DotChartOutlined',
    uri: '/demo/demo1',
    children: null
  },
  {
    id: '2',
    title: 'Option 2',
    icon: '',
    uri: '/demo/demo2',
    children: null
  },
  {
    id: '3',
    title: 'Navigation 3',
    icon: '',
    uri: null,
    children: [
      {
        id: '3.1',
        title: 'Navigation 3.1',
        icon: 'RadarChartOutlined',
        uri: '/demo/demo3',
        children: null
      },
      {
        id: '3.2',
        title: 'Navigation 3.2',
        icon: '',
        uri: '/demo/demo4',
        children: null
      }
    ]
  },
  {
    id: '4',
    title: 'Navigation 4',
    icon: '',
    uri: null,
    children: [
      {
        id: '4.1',
        title: 'Navigation 4.1',
        icon: 'RadarChartOutlined',
        uri: null,
        children: [
          {
            id: '4.1.1',
            title: 'Option 4.1.1',
            icon: 'RadarChartOutlined',
            uri: '/demo/demo5',
            children: null
          },
          {
            id: '4.1.2',
            title: 'Option 4.1.2',
            icon: '',
            uri: '/demo/demo6',
            children: null
          }
        ]
      },
      {
        id: '4.2',
        title: 'Navigation 4.2',
        icon: '',
        uri: null,
        children: [
          {
            id: '4.2.1',
            title: 'Option 4.2.1',
            icon: '',
            uri: '/demo/demo7',
            children: null
          },
          {
            id: '4.2.2',
            title: 'Option 4.2.2',
            icon: '',
            uri: '/demo/demo8',
            children: null
          }
        ]
      }
    ]
  }
]
</script>

<style lang="scss">

</style>
